NexusPi Git Node
Provisioning.cpp fc463eb4c579bbcd7340546e598044bd8345f3a5 (fc463eb4) Text, 12.17 KB
T8b949e// Copyright (C) 2026, Chad Attermann
T8b949e// This program is free software: you can redistribute it and/or modify
T8b949e// it under the terms of the GNU General Public License as published by
T8b949e// the Free Software Foundation, either version 3 of the License, or
T8b949e// (at your option) any later version.
T8b949e// This program is distributed in the hope that it will be useful,
T8b949e// but WITHOUT ANY WARRANTY; without even the implied warranty of
T8b949e// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
T8b949e// GNU General Public License for more details.
Tff7b72#Tff7b72include T8b949e"Provisioning.h"
T8b949e//#include "Config.h"
Tff7b72#Tff7b72ifdef HAS_PROVISIONING
T8b949e// KISS framing constants. We don't include "Framing.h" because it defines
T8b949e// the parser's module-state globals (IN_FRAME, ESCAPE, command, frame_len)
T8b949e// at file scope without extern guards — pulling it into a second TU
T8b949e// produces ODR clashes. The wire-format values below are protocol
T8b949e// constants and must match Framing.h's definitions.
Tff7b72#Tff7b72define FEND 0xC0
Tff7b72#Tff7b72define CMD_LOG 0x80
Tff7b72#Tff7b72define CMD_PROVISION_RSP 0x87
Tff7b72#Tff7b72include T8b949e<microReticulum/Interface.h>
Tff7b72#Tff7b72include T8b949e<microReticulum/Provisioning/Provisioning.h>
Tff7b72#Tff7b72include T8b949e<string>
Tff7b72#Tff7b72include T8b949e<vector>
T8b949e// lora_interface is always declared in RNode_Firmware.ino (constructed
T8b949e// with RNS::Type::NONE), even when LORA_TRANSPORT is not defined. Its
T8b949e// operator bool() returns true only after setup() assigns it a real
T8b949e// LoRaInterface implementation — so a single runtime check works in
T8b949e// both compile configurations.
Tff7b72extern Te6edf3RNSTff7b72:Tff7b72:Te6edf3Interface Te6edf3lora_interfaceTb4b4b4;
Tff7b72extern Tffa657int Te6edf3lora_sfTb4b4b4;
Tff7b72extern Tffa657int Te6edf3lora_crTb4b4b4;
Tff7b72extern Tffa657int Te6edf3lora_txpTb4b4b4;
Tff7b72extern Tffa657uint32_t Te6edf3lora_bwTb4b4b4;
Tff7b72extern Tffa657uint32_t Te6edf3lora_freqTb4b4b4;
Tff7b72extern Tffa657uint32_t Te6edf3lora_bitrateTb4b4b4;
Tff7b72extern Tffa657int Te6edf3noise_floorTb4b4b4;
Tff7b72extern Tffa657int Te6edf3current_rssiTb4b4b4;
Tff7b72extern Tffa657int Te6edf3last_rssiTb4b4b4;
Tff7b72extern Tffa657uint8_t Te6edf3last_rssi_rawTb4b4b4;
Tff7b72extern Tffa657uint8_t Te6edf3last_snr_rawTb4b4b4;
Tff7b72#Tff7b72if defined(UDP_TRANSPORT)
T8b949e// udp_interface is only declared in RNode_Firmware.ino under UDP_TRANSPORT,
T8b949e// so this extern (and its dependents) must stay behind the same guard.
Tff7b72extern Te6edf3RNSTff7b72:Tff7b72:Te6edf3Interface Te6edf3udp_interfaceTb4b4b4;
Tff7b72extern Te6edf3IPAddress Te6edf3wr_device_ipTb4b4b4;
Tff7b72extern Tffa657uint16_t Te6edf3udp_portTb4b4b4;
Tff7b72extern Tffa657uint8_t Te6edf3wifi_modeTb4b4b4;
Tff7b72extern Tffa657char Te6edf3wr_ssidTb4b4b4[Tb4b4b4]Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72extern Tffa657bool Te6edf3kiss_framed_logsTb4b4b4;
Tff7b72extern Tffa657bool Te6edf3nomadnet_enabledTb4b4b4;
T8b949e// ---------------------------------------------------------------------------
T8b949e// External hooks into the rest of the firmware.
T8b949e//
T8b949e// serial_write / escaped_serial_write are defined inline in Utilities.h
T8b949e// (compiled in the RNode_Firmware.ino TU). Forward-declaring them here
T8b949e// avoids pulling Utilities.h — which is not include-guarded and contains
T8b949e// file-scope globals — into a second translation unit.
T8b949e//
T8b949e// Radio config knobs and op_mode live in Config.h's global namespace and
T8b949e// are only referenced by the (currently commented-out) radio namespace
T8b949e// registration below. Pulling Config.h is enough since they're declared
T8b949e// there at file scope.
T8b949e// ---------------------------------------------------------------------------
Tff7b72extern Tffa657void Td2a8ffserial_writeTb4b4b4(Tffa657uint8_t Te6edf3byteTb4b4b4)Tb4b4b4;
Tff7b72extern Tffa657void Td2a8ffescaped_serial_writeTb4b4b4(Tffa657uint8_t Te6edf3byteTb4b4b4)Tb4b4b4;
T8b949e// ---------------------------------------------------------------------------
T8b949e// Public globals
T8b949e// ---------------------------------------------------------------------------
Tffa657bool Te6edf3provisioning_started Tff7b72= Tffa657falseTb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3Bytes Te6edf3provision_rx_bufTb4b4b4;
T8b949e// ---------------------------------------------------------------------------
T8b949e// Register Provisioning namespaces. Called from init_provisioning()
T8b949e// before Manager::begin().
T8b949e//
T8b949e// The "radio" namespace registration is kept here purely as reference —
T8b949e// EEPROM is currently the source of truth for radio configuration and a
T8b949e// future revival of Provisioning-backed radio config will need its own
T8b949e// migration strategy. See git history around the original Provisioning
T8b949e// integration for the prior wiring.
T8b949e// ---------------------------------------------------------------------------
Tff7b72static Tffa657void Td2a8ffregister_provisioning_namespacesTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787ProvisioningTb4b4b4;
T8b949e// ----- general namespace -----
Tff7b72auto Te6edf3general Tff7b72= Te6edf3ManagerTff7b72:Tff7b72:Te6edf3instanceTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3register_namespaceTb4b4b4(Ta5d6ff"Ta5d6ffGeneralTa5d6ff"Tb4b4b4, Te6edf3PROV_NS_GENERALTb4b4b4)
Tb4b4b4.Te6edf3field_boolTb4b4b4(Ta5d6ff"Ta5d6ffkiss_framed_logsTa5d6ff"Tb4b4b4, Te6edf3PROV_GENERAL_KISS_LOGTb4b4b4, Te6edf3FF_LIVE_APPLYTb4b4b4, Te6edf3kiss_framed_logsTb4b4b4,
Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3ValueTff7b72& Te6edf3vTb4b4b4) Tb4b4b4{ Te6edf3kiss_framed_logs Tff7b72= Te6edf3vTb4b4b4.Te6edf3as_boolTb4b4b4(Tb4b4b4)Tb4b4b4; Tff7b72return Tffa657trueTb4b4b4; Tb4b4b4}Tb4b4b4,
Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3kiss_framed_logsTb4b4b4; Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef URTN_STATS_PAGES
Te6edf3general
Tb4b4b4.Te6edf3field_boolTb4b4b4(Ta5d6ff"Ta5d6ffnomadnet_enabledTa5d6ff"Tb4b4b4, Te6edf3PROV_GENERAL_NOMADNETTb4b4b4, Te6edf3FF_REBOOT_REQUIREDTb4b4b4, Te6edf3nomadnet_enabledTb4b4b4,
Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3ValueTff7b72& Te6edf3vTb4b4b4) Tb4b4b4{ Te6edf3nomadnet_enabled Tff7b72= Te6edf3vTb4b4b4.Te6edf3as_boolTb4b4b4(Tb4b4b4)Tb4b4b4; Tff7b72return Tffa657trueTb4b4b4; Tb4b4b4}Tb4b4b4,
Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3nomadnet_enabledTb4b4b4; Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(LORA_TRANSPORT)
Tff7b72if Tb4b4b4(Te6edf3lora_interfaceTb4b4b4) Tb4b4b4{
Te6edf3general
Tb4b4b4.Te6edf3field_enumTb4b4b4(
Ta5d6ff"Ta5d6fflora_interface_modeTa5d6ff"Tb4b4b4, Te6edf3PROV_GENERAL_LORA_MODETb4b4b4, Te6edf3FF_LIVE_APPLYTb4b4b4, Tff7b72static_castTff7b72<Te6edf3fint_tTff7b72>Tb4b4b4(Te6edf3lora_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
T8b949e/* values */ Tb4b4b4{
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_GATEWAYTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_FULLTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_POINT_TO_POINTTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ACCESS_POINTTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_BOUNDARYTb4b4b4,
Tb4b4b4}Tb4b4b4,
T8b949e/* labels */ Tb4b4b4{
Ta5d6ff"Ta5d6ffgatewayTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fffullTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpoint-to-pointTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffaccess-pointTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffroamingTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffboundaryTa5d6ff" Tb4b4b4}Tb4b4b4,
T8b949e/* setter */ Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3ValueTff7b72& Te6edf3vTb4b4b4) Tb4b4b4{
Te6edf3lora_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tff7b72static_castTff7b72<Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3modesTff7b72>Tb4b4b4(Te6edf3vTb4b4b4.Te6edf3as_intTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4; Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}Tb4b4b4,
T8b949e/* getter */ Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72static_castTff7b72<Te6edf3fint_tTff7b72>Tb4b4b4(Te6edf3lora_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(UDP_TRANSPORT)
Tff7b72if Tb4b4b4(Te6edf3udp_interfaceTb4b4b4) Tb4b4b4{
Te6edf3general
Tb4b4b4.Te6edf3field_enumTb4b4b4(
Ta5d6ff"Ta5d6ffudp_interface_modeTa5d6ff"Tb4b4b4, Te6edf3PROV_GENERAL_UDP_MODETb4b4b4, Te6edf3FF_LIVE_APPLYTb4b4b4, Tff7b72static_castTff7b72<Te6edf3fint_tTff7b72>Tb4b4b4(Te6edf3udp_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
T8b949e/* values */ Tb4b4b4{
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_GATEWAYTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_FULLTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_POINT_TO_POINTTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ACCESS_POINTTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4,
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_BOUNDARYTb4b4b4,
Tb4b4b4}Tb4b4b4,
T8b949e/* labels */ Tb4b4b4{
Ta5d6ff"Ta5d6ffgatewayTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fffullTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpoint-to-pointTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffaccess-pointTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffroamingTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffboundaryTa5d6ff" Tb4b4b4}Tb4b4b4,
T8b949e/* setter */ Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3ValueTff7b72& Te6edf3vTb4b4b4) Tb4b4b4{
Te6edf3udp_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tff7b72static_castTff7b72<Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3modesTff7b72>Tb4b4b4(Te6edf3vTb4b4b4.Te6edf3as_intTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4; Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}Tb4b4b4,
T8b949e/* getter */ Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72static_castTff7b72<Te6edf3fint_tTff7b72>Tb4b4b4(Te6edf3udp_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Te6edf3general
Tb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// close "General"
T8b949e// ----- Metrics namespace -----
T8b949e//
T8b949e// The Metrics > Interfaces parent chain is opened unconditionally; the
T8b949e// per-interface child namespaces are added only when the corresponding
T8b949e// interface object reports it has a live implementation (operator bool
T8b949e// on RNS::Interface). Compile-time guards remain only where they need
T8b949e// to — UDP's externs aren't declared without UDP_TRANSPORT.
Tff7b72auto Te6edf3metrics_ifaces Tff7b72= Te6edf3ManagerTff7b72:Tff7b72:Te6edf3instanceTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3namespace_Tb4b4b4(Ta5d6ff"Ta5d6ffMetricsTa5d6ff"Tb4b4b4, Te6edf3PROV_NS_METRICSTb4b4b4)
Tb4b4b4.Te6edf3namespace_Tb4b4b4(Ta5d6ff"Ta5d6ffInterfacesTa5d6ff"Tb4b4b4, Te6edf3PROV_NS_METRICS_IFACETb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(LORA_TRANSPORT)
Tff7b72if Tb4b4b4(Te6edf3lora_interfaceTb4b4b4) Tb4b4b4{
Te6edf3metrics_ifaces
T8b949e//.namespace_("LoRa", PROV_NS_IFACE_LORA)
Tb4b4b4.Te6edf3namespace_Tb4b4b4(Te6edf3lora_interfaceTb4b4b4.Te6edf3nameTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PROV_NS_IFACE_LORATb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6fffrequencyTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_FREQTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3lora_freqTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6ffbandwidthTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_BWTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3lora_bwTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6ffspreading_factorTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_SFTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3lora_sfTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6ffcoding_rateTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_CRTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3lora_crTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6fftx_powerTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_TXPTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3lora_txpTb4b4b4; Tb4b4b4}Tb4b4b4)
T8b949e//.metric_int("current_rssi", PROV_METRICS_LORA_CRSSI, []() { return last_rssi+rssi_offset; })
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6ffcurrent_rssiTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_CRSSITb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3current_rssiTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6ffnoise_floorTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_NFTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3noise_floorTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6fflast_rssiTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_LRSSITb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3last_rssiTff7b72+T79c0ff157Tb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6fflast_snrTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_LORA_LSNRTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3last_snr_rawTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(UDP_TRANSPORT)
Tff7b72if Tb4b4b4(Te6edf3udp_interfaceTb4b4b4) Tb4b4b4{
Te6edf3metrics_ifaces
T8b949e//.namespace_("UDP", PROV_NS_IFACE_UDP)
Tb4b4b4.Te6edf3namespace_Tb4b4b4(Te6edf3udp_interfaceTb4b4b4.Te6edf3nameTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PROV_NS_IFACE_LORATb4b4b4)
Tb4b4b4.Te6edf3metric_stringTb4b4b4(Ta5d6ff"Ta5d6ffip_addrTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_UDP_ADDRTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3wr_device_ipTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_intTb4b4b4(Ta5d6ff"Ta5d6ffudp_portTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_UDP_PORTTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3udp_portTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3metric_stringTb4b4b4(Ta5d6ff"Ta5d6ffwifi_ssidTa5d6ff"Tb4b4b4, Te6edf3PROV_METRICS_WIFI_SSIDTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3wr_ssidTb4b4b4; Tb4b4b4}Tb4b4b4)
Tb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Te6edf3metrics_ifaces
Tb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4) T8b949e// close "Interfaces"
Tb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// close "Metrics"
T8b949e// ----- radio namespace (DISABLED) -----
T8b949e//
T8b949e// Manager::instance()
T8b949e// .register_namespace("radio", PROV_NS_RADIO)
T8b949e// .field_enum("op_mode", PROV_RADIO_OP_MODE, FF_REBOOT_REQUIRED,
T8b949e// (fint_t)MODE_HOST,
T8b949e// std::vector<fint_t>{ (fint_t)MODE_HOST, (fint_t)MODE_TNC },
T8b949e// std::vector<std::string>{ "host", "tnc" },
T8b949e// [](const Value& v) { op_mode = (uint8_t)v.as_int(); return true; })
T8b949e// .field_int("frequency", PROV_RADIO_FREQ, FF_REBOOT_REQUIRED,
T8b949e// (fint_t)0, (fint_t)100000000, (fint_t)1000000000,
T8b949e// [](const Value& v) { lora_freq = (uint32_t)v.as_int(); return true; })
T8b949e// .field_int("bandwidth", PROV_RADIO_BW, FF_REBOOT_REQUIRED,
T8b949e// (fint_t)0, (fint_t)7800, (fint_t)500000,
T8b949e// [](const Value& v) { lora_bw = (uint32_t)v.as_int(); return true; })
T8b949e// .field_int("sf", PROV_RADIO_SF, FF_REBOOT_REQUIRED,
T8b949e// (fint_t)0, (fint_t)5, (fint_t)12,
T8b949e// [](const Value& v) { lora_sf = (int)v.as_int(); return true; })
T8b949e// .field_int("cr", PROV_RADIO_CR, FF_REBOOT_REQUIRED,
T8b949e// (fint_t)5, (fint_t)5, (fint_t)8,
T8b949e// [](const Value& v) { lora_cr = (int)v.as_int(); return true; })
T8b949e// .field_int("txp", PROV_RADIO_TXP, FF_REBOOT_REQUIRED,
T8b949e// (fint_t)0xFF, (fint_t)-9, (fint_t)22,
T8b949e// [](const Value& v) { lora_txp = (int)v.as_int(); return true; })
T8b949e// .field_int("implicit_l", PROV_RADIO_IMPLICIT, FF_REBOOT_REQUIRED,
T8b949e// (fint_t)0, (fint_t)0, (fint_t)255,
T8b949e// [](const Value& v) { implicit_l = (uint8_t)v.as_int(); return true; })
T8b949e// .end();
Tb4b4b4}
T8b949e// ---------------------------------------------------------------------------
T8b949e// Bring the Provisioning subsystem up. Loads any persisted MsgPack files
T8b949e// under /config (built-in Reticulum / Transport namespaces auto-register
T8b949e// inside begin(); our general namespace is registered above). The
T8b949e// on_reboot_requested callback is wired up but intentionally a no-op —
T8b949e// the host orchestrates reboots via CMD_RESET.
T8b949e// ---------------------------------------------------------------------------
Tffa657void Te6edf3init_provisioningTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3RNSTff7b72:Tff7b72:Te6edf3ProvisioningTff7b72:Tff7b72:Te6edf3ManagerTff7b72:Tff7b72:Te6edf3instanceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3on_reboot_requestedTb4b4b4(Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Host orchestrates reboot via CMD_RESET. Manager::needs_reboot()
T8b949e// remains queryable via GetInfo for callers that want to surface
T8b949e// pending-reboot state.
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3register_provisioning_namespacesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3ProvisioningTff7b72:Tff7b72:Te6edf3ManagerTff7b72:Tff7b72:Te6edf3instanceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3beginTb4b4b4(Ta5d6ff"Ta5d6ff/configTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3provisioning_started Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// ---------------------------------------------------------------------------
T8b949e// Request / response over KISS
T8b949e// ---------------------------------------------------------------------------
Tffa657void Te6edf3on_provision_requestTb4b4b4(Tff7b72const Te6edf3RNSTff7b72:Tff7b72:Te6edf3BytesTff7b72& Te6edf3reqTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3provisioning_startedTb4b4b4) Tff7b72returnTb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3Bytes Te6edf3response Tff7b72= Te6edf3RNSTff7b72:Tff7b72:Te6edf3ProvisioningTff7b72:Tff7b72:Te6edf3ManagerTff7b72:Tff7b72:Te6edf3instanceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3handle_messageTb4b4b4(Te6edf3reqTb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_provision_responseTb4b4b4(Te6edf3responseTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3kiss_indicate_provision_responseTb4b4b4(Tff7b72const Te6edf3RNSTff7b72:Tff7b72:Te6edf3BytesTff7b72& Te6edf3payloadTb4b4b4) Tb4b4b4{
Te6edf3serial_writeTb4b4b4(Te6edf3FENDTb4b4b4)Tb4b4b4;
Te6edf3serial_writeTb4b4b4(Te6edf3CMD_PROVISION_RSPTb4b4b4)Tb4b4b4;
Tff7b72const Tffa657uint8_tTff7b72* Te6edf3data Tff7b72= Te6edf3payloadTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3n Tff7b72= Te6edf3payloadTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3nTb4b4b4; Tff7b72+Tff7b72+Te6edf3iTb4b4b4) Te6edf3escaped_serial_writeTb4b4b4(Te6edf3dataTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3serial_writeTb4b4b4(Te6edf3FENDTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif T8b949e// HAS_PROVISIONING
Served by rngit 1.5.2 - Generated in 0.03s